• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /macosx-10.10.1/pyobjc-45/2.6/pyobjc/pyobjc-framework-Quartz/Examples/Programming with Quartz/BasicDrawing/
1from Quartz import *
2
3import Images
4import DataProvidersAndConsumers
5import Utilities
6
7import sys
8
9def exportImageWithMaskFromURLWithDestination(context, imageURL,
10        imagewidth, imageheight, bitsPerComponent,
11        theMaskingImageURL, maskwidth, maskheight):
12
13    imageBitsPerPixel = bitsPerComponent * 3
14    bytesPerRow = ((imagewidth * imageBitsPerPixel) + 7)/8
15    shouldInterpolate = True
16    imageDataProvider = CGDataProviderCreateWithURL(imageURL)
17    if imageDataProvider is None:
18        print >>sys.stderr, "Couldn't create Image Data provider!"
19        return
20
21    colorspace = Utilities.getTheCalibratedRGBColorSpace()
22    image = CGImageCreate(imagewidth, imageheight, bitsPerComponent,
23                        imageBitsPerPixel, bytesPerRow, colorspace,
24                        kCGImageAlphaNone, imageDataProvider,
25                        None, shouldInterpolate,
26                        kCGRenderingIntentDefault)
27    del imageDataProvider
28    if image is None:
29        print >>sys.stderr, "Couldn't create CGImageRef for this data!"
30        return
31
32    imageRect = CGRectMake(0.0,imageheight, imagewidth, imageheight)
33    # Draw the image.
34    CGContextDrawImage(context, imageRect, image)
35
36    # Now the mask.
37    maskDataProvider = CGDataProviderCreateWithURL(theMaskingImageURL)
38    if maskDataProvider is None:
39        print >>sys.stderr, "Couldn't create Image Data provider!"
40        return
41
42    mask = CGImageMaskCreate(maskwidth, maskheight, bitsPerComponent,
43                            bitsPerComponent, maskwidth,
44                            maskDataProvider, None, shouldInterpolate)
45    del maskDataProvider
46    if mask is None:
47        print >>sys.stderr, "Couldn't create CGImageRef for mask data!"
48        return
49
50    # Draw the mask below the image.
51    maskRect = CGRectMake(0.0, 0.0, maskwidth, maskheight)
52    CGContextDrawImage(context, maskRect, mask)
53
54    # Create a new CGImage object, the image, masked with mask.
55    imageMaskedWithImage = CGImageCreateWithMask(image, mask)
56    # Once the new image is created, we can release the image
57    # and the mask which make it up. Quartz retains what it needs
58    # for the new masked image.
59    del image
60    del mask
61
62    if imageMaskedWithImage is None:
63        print >>sys.stderr, "Couldn't create image masked with mask!"
64        return
65
66    imageRect = CGRectMake(imagewidth, imageheight/2, imagewidth, imageheight)
67    # Draw the masked image to the right of the image and its mask.
68    CGContextDrawImage(context, imageRect, imageMaskedWithImage)
69
70    # Of course this is a total hack.
71    outPath = "/tmp/imageout.png"
72    exportURL = CFURLCreateFromFileSystemRepresentation(None,
73				    outPath, len(outPath), False)
74
75    if exportURL is not None:
76        Images.exportCGImageToPNGFileWithDestination(imageMaskedWithImage, exportURL)
77
78_data = ''.join(map(chr, (
79	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
80	0xFE, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x03, 0xFF, 0xFF,
81	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xF8, 0xE7, 0xFF, 0xFF, 0xFF, 0xFF,
82	0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x40, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0,
83	0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00,
84	0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
85	0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00,
86	0x00, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
87	0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF,
88	0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00,
89	0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90	0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF,
91	0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
92	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93	0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF,
94	0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
95	0x00, 0x00, 0x01, 0xC0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xF8,
96	0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xF8, 0x00, 0x00, 0x7F, 0xFF,
97	0xFF, 0xFE, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
98	0x00, 0x7F, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFC,
99	0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
100	0xFF, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
101	0x0F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF,
102	0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF,
103	0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x80, 0x01, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00,
104	0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF,
105	0x80, 0x00, 0x1F, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF,
106	0xFF, 0xF8, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00,
107	0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFE,
108	0x40, 0x00, 0x0F, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF,
109	0xFF, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x01,
110	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFC, 0x00, 0x05, 0xEF, 0xFF, 0xFE, 0x00,
111	0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xF0, 0x00, 0x3F, 0x00, 0x03, 0xFC, 0x00, 0x00, 0x00, 0x3F, 0xFF,
112	0xFF, 0xE0, 0x00, 0x7C, 0x00, 0x00, 0x78, 0x1F, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xC0, 0x00, 0x38,
113	0x00, 0x00, 0x78, 0x3C, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x78, 0x00, 0x00, 0x70, 0x18,
114	0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x78, 0x1F, 0x00, 0x30, 0x00, 0x00, 0x01, 0xFF, 0xFF,
115	0xFF, 0xFE, 0x00, 0x7C, 0x3F, 0x00, 0x18, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00,
116	0x00, 0x00, 0x38, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x80, 0x00, 0x3C, 0x00,
117	0x0C, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x20, 0x1C, 0x03, 0xFF, 0xFF,
118	0xFF, 0xFF, 0x00, 0x00, 0x04, 0x00, 0x3C, 0x00, 0x3C, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x70,
119	0xBF, 0x86, 0x3C, 0x1F, 0xFC, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x11, 0xF0, 0x0E, 0x3C, 0x1F,
120	0xFE, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xA0, 0x19, 0xF0, 0x0C, 0x3C, 0x0F, 0xFF, 0x0B, 0xFF, 0xFF,
121	0xFF, 0xFF, 0xB0, 0x1D, 0xFE, 0x1C, 0x7E, 0x0F, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xB8, 0x1C,
122	0xFF, 0x3C, 0xFE, 0x03, 0xFE, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x1E, 0x7F, 0xF8, 0xDE, 0x00,
123	0x7C, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1E, 0x7F, 0xF1, 0xDF, 0x30, 0x03, 0x83, 0xFF, 0xFF,
124	0xFF, 0xFF, 0xFE, 0x1F, 0x3F, 0xE3, 0x9F, 0x10, 0x3F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x0F,
125	0xFF, 0x83, 0xDF, 0x80, 0x1F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x03, 0xFC, 0x03, 0xDF, 0x81,
126	0x8F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x07, 0xFE, 0x1F, 0x8F, 0x00, 0x07, 0x83, 0xFF, 0xFF,
127	0xFF, 0xFF, 0xFF, 0x07, 0xFE, 0x3C, 0x06, 0x00, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
128	0xFC, 0x7C, 0x00, 0x00, 0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xF8, 0x7F, 0x00, 0x00,
129	0x01, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01, 0xF8, 0xFF, 0xE0, 0x30, 0x01, 0x83, 0xFF, 0xFF,
130	0xFF, 0xFF, 0xFF, 0x00, 0xF1, 0xEF, 0xF9, 0xE0, 0x03, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
131	0xF1, 0xFF, 0xFF, 0x80, 0x0F, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x03, 0xE2, 0xFF, 0xFE, 0x00,
132	0x1F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x83, 0xF0, 0x00, 0x00, 0x1C, 0x3F, 0x87, 0xFF, 0xFF,
133	0xFF, 0xFF, 0xFF, 0xC3, 0xF0, 0x00, 0x01, 0xF8, 0x0F, 0x87, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC3,
134	0xF0, 0x03, 0xFF, 0xF0, 0x5F, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC1, 0xFF, 0xC7, 0xFF, 0xE0,
135	0x7F, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xF1, 0xFF, 0x80, 0x2F, 0x0F, 0xFF, 0xFF,
136	0xFF, 0xFF, 0xFF, 0xE1, 0xFF, 0xF8, 0x0F, 0xC0, 0x06, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4,
137	0xFF, 0xFE, 0x0F, 0xF8, 0x44, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF4, 0xFF, 0xFF, 0xFF, 0xF8,
138	0x64, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF9, 0xFF, 0xFF, 0xFF, 0x3C, 0xE4, 0x7F, 0xFF, 0xFF,
139	0xFF, 0xFF, 0xFF, 0xFD, 0x9F, 0xFF, 0xFC, 0x1F, 0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD,
140	0x1F, 0xFF, 0xFC, 0x03, 0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x01, 0xFF, 0xFF, 0xFF,
141	0xC0, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF,
142	0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
143	0x80, 0x7F, 0xFF, 0xFF, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x80, 0x1F, 0xFF, 0xFF,
144	0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xC0, 0x0F, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF,
145	0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x07, 0xFF, 0xFF, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
146	0xF0, 0x03, 0xFF, 0xFF, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x70, 0x01, 0xFF, 0xFC,
147	0x00, 0x17, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x78, 0x00, 0x7F, 0xF0, 0x00, 0x07, 0xFF, 0xFF,
148	0xFF, 0xFF, 0xFF, 0xF0, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x03,
149	0xFE, 0x00, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1F, 0xFF, 0x80, 0x00, 0x00,
150	0x00, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x7F, 0x7F, 0xC0, 0x00, 0x00, 0x00, 0x07, 0xFF, 0xFF
151    )))
152
153def getMaskData1():
154    return _data
155
156_data2 = ''.join(map(chr, (
157	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
158	0xFF, 0xFF, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x1F,
159	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF,
160	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
161	0xFF, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00,
162	0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0xFF,
163	0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
164	0xE0, 0x00, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00,
165	0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF,
166	0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE,
167	0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00,
168	0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF,
169	0xFF, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8,
170	0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x01,
171	0x80, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x03, 0xC0, 0x07, 0xFF, 0xFF,
172	0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x00, 0x0B, 0xE0, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0,
173	0x00, 0x00, 0x00, 0x07, 0xF0, 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0x00, 0x1F,
174	0xF4, 0x83, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xE4, 0x03, 0xFF, 0xFF,
175	0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00, 0x3F, 0xE4, 0x43, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
176	0x00, 0x00, 0x00, 0x3F, 0xE4, 0x4B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x02, 0xFF,
177	0xE4, 0x5B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x02, 0xFF, 0xE0, 0x5B, 0xFF, 0xFF,
178	0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x07, 0xC1, 0xFF, 0xE0, 0x59, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x18,
179	0x00, 0x7F, 0xF0, 0xFE, 0x00, 0x79, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x18, 0x00, 0x78, 0x0F, 0xFE,
180	0x04, 0xE1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x18, 0x00, 0xB0, 0x47, 0xFF, 0xFF, 0xE1, 0xFF, 0xFF,
181	0xFF, 0xFF, 0xFE, 0x10, 0x00, 0xC4, 0x69, 0xFF, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x10,
182	0x01, 0xFF, 0xE1, 0xFC, 0x07, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x00, 0x01, 0xFF, 0xF8, 0x78,
183	0x01, 0xC5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x04, 0x01, 0xFF, 0xF0, 0x78, 0x01, 0xC5, 0xFF, 0xFF,
184	0xFF, 0xFF, 0xFC, 0x0C, 0x00, 0xFF, 0xF8, 0x7E, 0x3F, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x0C,
185	0x00, 0x7F, 0xF0, 0x18, 0xFF, 0xC3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x07, 0x00, 0x7F, 0xF4, 0x1F,
186	0xFF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x23, 0x00, 0x7F, 0xE0, 0x3E, 0xFF, 0xE3, 0xFF, 0xFF,
187	0xFF, 0xFF, 0xF8, 0x11, 0x00, 0x7F, 0xEC, 0x5F, 0xBF, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x01,
188	0x00, 0x3F, 0xCE, 0x7E, 0x3F, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x08, 0x00, 0x7F, 0x80, 0x2E,
189	0x3F, 0xE3, 0xFF, 0xFF, 0xFF, 0xFF, 0xF8, 0x06, 0x00, 0x7F, 0x00, 0x6E, 0x3F, 0xEB, 0xFF, 0xFF,
190	0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x7E, 0x0D, 0xFE, 0xFF, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
191	0x00, 0x3C, 0x00, 0xFE, 0x3F, 0xEB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x50, 0x00, 0xFE,
192	0x3F, 0xCB, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0x01, 0x98, 0xFF, 0x3F, 0xCB, 0xFF, 0xFF,
193	0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xC7, 0xE1, 0xFF, 0x3F, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
194	0x00, 0x40, 0xFF, 0xFF, 0xBF, 0x8B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xE0, 0x1F, 0xFF,
195	0xDF, 0x0B, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00, 0x00, 0xE8, 0x63, 0xFF, 0xDF, 0x0F, 0xFF, 0xFF,
196	0xFF, 0xFF, 0xF0, 0x00, 0x02, 0xFC, 0xF9, 0xFF, 0xEF, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xF0, 0x00,
197	0x03, 0xFE, 0x7F, 0xF8, 0x1E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x03, 0x7E, 0x0F, 0xF9,
198	0xBE, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x01, 0x7F, 0xC1, 0xF3, 0xFC, 0x05, 0xFF, 0xFF,
199	0xFF, 0xFF, 0xE0, 0x00, 0x01, 0x3D, 0xF8, 0x0F, 0x7C, 0x05, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00,
200	0x01, 0xBC, 0x7F, 0xFF, 0xF8, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xE0, 0x00, 0x00, 0xBE, 0xFF, 0xFF,
201	0xF8, 0x02, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x1D, 0xFF, 0xFF, 0xF0, 0x00, 0xFF, 0xFF,
202	0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x0F, 0xF7, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xC0, 0x00,
203	0x00, 0x0F, 0xF3, 0xFF, 0xE0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x03, 0xF3, 0xFF,
204	0xC0, 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x01, 0xF7, 0xFF, 0x80, 0x00, 0x3F, 0xFF,
205	0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x3F, 0xFF, 0x00, 0x00, 0x3F, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
206	0x00, 0x00, 0x1F, 0xFF, 0x00, 0x20, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF,
207	0x00, 0x10, 0x3F, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x1F, 0xFF, 0x00, 0x10, 0x3F, 0xFF,
208	0xFF, 0xFC, 0x00, 0x00, 0x02, 0x00, 0x0F, 0xFF, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xFC, 0x00, 0x00,
209	0x04, 0x00, 0x1F, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x07, 0x81, 0x7F, 0xFE,
210	0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF8, 0x00, 0x00, 0x03, 0xDF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF,
211	0xFF, 0xF8, 0x00, 0x00, 0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x00,
212	0x07, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x1F, 0xFF, 0xFF, 0xF0, 0x00, 0x40, 0x07, 0xFF, 0xFF, 0xFE,
213	0x00, 0x00, 0x0F, 0xFF, 0xFF, 0xF0, 0x00, 0xC0, 0x03, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x0F, 0xFF,
214	0xFF, 0xE0, 0x00, 0xE0, 0x07, 0xFF, 0xFF, 0xFE, 0x81, 0x00, 0x07, 0xFF, 0xFF, 0xC0, 0x01, 0xE0,
215	0x07, 0xFF, 0xFF, 0xFE, 0x01, 0x00, 0x07, 0xFF, 0xFF, 0x80, 0x0F, 0xF0, 0x03, 0xFF, 0xFF, 0xFE,
216	0x83, 0x80, 0x03, 0xFF, 0xFF, 0x00, 0x1F, 0xF0, 0x13, 0xFF, 0xFF, 0xFE, 0x03, 0xE0, 0x01, 0xFF,
217	0xFC, 0x03, 0x3F, 0xF0, 0x21, 0xFF, 0xFF, 0xFE, 0x03, 0xFC, 0x00, 0x3F, 0xF0, 0x3F, 0x3F, 0xF8,
218	0x3B, 0xFF, 0xFF, 0xFE, 0x03, 0xFE, 0xC0, 0x0F, 0xE3, 0xFB, 0x7F, 0xF8, 0x3B, 0xFF, 0xFF, 0xFF,
219	0x07, 0xFF, 0xFF, 0x07, 0x9F, 0xFB, 0x7F, 0xFC, 0x79, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF,
220	0xFF, 0xFF, 0x7F, 0xFC, 0x39, 0xFF, 0xFF, 0xFF, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE,
221	0x3F, 0xFF, 0xFF, 0xFE, 0x07, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0x1F, 0xFF, 0xFF, 0xFE,
222	0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0x1F, 0x7F, 0xFF, 0xFE, 0x0F, 0xFF, 0xFF, 0xFF,
223	0xFF, 0xFF, 0x7F, 0xFF, 0x1F, 0xFE, 0xFF, 0xFC, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
224	0x0F, 0xFF, 0xFF, 0xFF, 0x1F, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x87, 0xFF, 0xFF, 0xFE,
225	0x1F, 0xFF, 0xEF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0x82, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xFF, 0xFF,
226	0xFF, 0xFF, 0xBF, 0xFF, 0x83, 0xFF, 0xFF, 0xFC, 0x3F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
227	0xC1, 0xFF, 0xFF, 0xF8, 0x7F, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xBF, 0xFF, 0xE0, 0xFF, 0xFF, 0xF0,
228	0xFF, 0xFF, 0xBF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
229    )))
230def getMaskData2():
231    return _data2
232
233
234def doOneBitMaskImages(context):
235    bitsPerComponent = 1
236    bitsPerPixel = 1
237    width = 96
238    height = 96
239    bytesPerRow = 12
240
241    imageDataSize = bytesPerRow*height
242    shouldInterpolate = True
243    lightBlue = [0.482, 0.62, 0.871, 1.0]
244    black = [0.0, 0.0, 0.0, 1.0]
245    darkRed = [0.663, 0., 0.031, 1.0]
246    darkGreen = [0.404, 0.808, 0.239, 1.0]
247    darkBlue = [0.11, 0.208, 0.451, 1.0]
248    purple = [0.69, 0.486, 0.722, 1.0]
249    darkOrange = [0.965, 0.584, 0.059, 1.0]
250
251    # A decode array contains two elements for each component. In this
252    # case, an image mask has one component so the array consists of
253    # two values. When using this decode array, a sample value of 0
254    # is mapped into the value 1, and the maximum sample value is
255    # mapped into the value 0. This inverts the sense of the mask data.
256    decode = (1 , 0)
257
258    # Create a Quartz data provider for the image data. Because this
259    # data is static data, we don't need to release it so the data
260    # release function is None.
261    data = getMaskData1()
262    dataProvider = CGDataProviderCreateWithData(None, data, imageDataSize, None)
263    if dataProvider is None:
264        print >>sys.stderr, "Couldn't create Mask1 Data provider!"
265        return
266
267    # Create a mask from the data.
268    mask1 = CGImageMaskCreate(width, height, bitsPerComponent,
269                                    bitsPerPixel, bytesPerRow, dataProvider,
270                                    None, shouldInterpolate)
271    # Create the same mask but with a decode array that
272    # inverts the sense of the mask.
273    invertedmask1 = CGImageMaskCreate(width, height,
274                                    bitsPerComponent, bitsPerPixel, bytesPerRow,
275                                    dataProvider, decode, shouldInterpolate)
276    # Release the data provider now that this code no longer needs it.
277    del dataProvider
278
279    if mask1 is None or invertedmask1 is None:
280        if mask1 is None:
281            print >>sys.stderr, "Couldn't create CGImageRef for the mask data 1!"
282
283        if invertedmask1 is None:
284            print >>sys.stderr, "Couldn't create CGImageRef for the inverted mask data 1!"
285        return
286
287    # Get the pointer to the data for the second mask.
288    data = getMaskData2()
289    dataProvider = CGDataProviderCreateWithData(None, data, imageDataSize, None)
290    if dataProvider is None:
291        print >>sys.stderr, "Couldn't create Mask2 Data provider!"
292        return
293
294    mask2 = CGImageMaskCreate(width, height, bitsPerComponent,
295                                bitsPerPixel, bytesPerRow, dataProvider,
296                                None, shouldInterpolate)
297    # Create the same mask but with a decode array that
298    # inverts the sense of the mask.
299    invertedmask2 = CGImageMaskCreate(width, height,
300                                    bitsPerComponent, bitsPerPixel, bytesPerRow,
301                                    dataProvider, decode, shouldInterpolate)
302    # Release the data provider now that this code no longer needs it.
303    del dataProvider
304    if mask2 is None or invertedmask2 is None:
305        if mask2 is None:
306            print >>sys.stderr, "Couldn't create CGImageRef for the mask data 2!"
307
308        if invertedmask2 is None:
309            print >>sys.stderr, "Couldn't create CGImageRef for the inverted mask data 2!"
310
311        return
312
313    CGContextScaleCTM(context, 1.5, 1.5)
314    colorSpace = Utilities.getTheCalibratedRGBColorSpace()
315    CGContextSetFillColorSpace(context, colorSpace);
316
317    # Set the fill color to a light blue.
318    CGContextSetFillColor(context, lightBlue)
319    # Paint part of the background.
320    backRect = CGRectMake(width/2, height/2, width*3, height)
321    CGContextFillRect(context, backRect)
322
323    imageRect = CGRectMake(0., height, width, height)
324    CGContextSaveGState(context)
325    # Set the fill color to opaque black.
326    CGContextSetFillColor(context, black)
327    # Mask 1.
328    CGContextDrawImage(context, imageRect, mask1)
329
330    CGContextTranslateCTM(context, width, 0)
331    # Set the fill color to opaque red.
332    CGContextSetFillColor(context, darkRed);
333    # Mask 2.
334    CGContextDrawImage(context, imageRect, mask2)
335    CGContextTranslateCTM(context, width, 0)
336    # Set the fill color to dark orange.
337    CGContextSetFillColor(context, darkOrange)
338    # Mask 3.
339    CGContextDrawImage(context, imageRect, mask1)
340
341    CGContextTranslateCTM(context, width, 0)
342    # Make the orange 50% transparent.
343    darkOrange[3] = 0.5
344    CGContextSetFillColor(context, darkOrange)
345    # Mask 4.
346    CGContextDrawImage(context, imageRect, mask2)
347    CGContextRestoreGState(context)
348
349    # Translate down the page. The cast is necessary
350    # since height is typed as size_t which is unsigned.
351    CGContextTranslateCTM(context, 0, -height)
352
353    # Set the fill color to an opaque green.
354    CGContextSetFillColor(context, darkGreen)
355    # Mask 5.
356    CGContextDrawImage(context, imageRect, invertedmask2)
357
358    CGContextTranslateCTM(context, width, 0)
359    # Set the fill color to a dark blue.
360    CGContextSetFillColor(context, darkBlue)
361    # Mask 6.
362    CGContextDrawImage(context, imageRect, invertedmask1)
363    CGContextTranslateCTM(context, width, 0)
364    # Set the fill color to purple.
365    CGContextSetFillColor(context, purple)
366    # Mask 7.
367    CGContextDrawImage(context, imageRect, invertedmask2)
368    CGContextTranslateCTM(context, width, 0)
369
370    # Make the purple 50% transparent.
371    purple[3] = 0.5
372    CGContextSetFillColor(context, purple)
373    # Mask 8.
374    CGContextDrawImage(context, imageRect, invertedmask1)
375
376def doMaskImageWithMaskFromURL(context, imageURL,
377        imagewidth, imageheight, bitsPerComponent,
378        theMaskingImageURL, maskwidth, maskheight):
379
380    imageBitsPerPixel = bitsPerComponent * 3
381    bytesPerRow = ((imagewidth * imageBitsPerPixel) + 7)/8
382    shouldInterpolate = True
383    imageDataProvider = CGDataProviderCreateWithURL(imageURL)
384    if imageDataProvider is None:
385        print >>sys.stderr,  "Couldn't create Image Data provider!"
386        return
387
388    colorspace = Utilities.getTheCalibratedRGBColorSpace()
389    image = CGImageCreate(imagewidth, imageheight, bitsPerComponent,
390                            imageBitsPerPixel, bytesPerRow, colorspace,
391                            kCGImageAlphaNone, imageDataProvider,
392                            None, shouldInterpolate,
393                            kCGRenderingIntentDefault)
394    del imageDataProvider
395    if image is None:
396        print >>sys.stderr, "Couldn't create CGImageRef for this data!"
397        return
398
399    imageRect = CGRectMake(0.0,imageheight, imagewidth, imageheight)
400    # Draw the image.
401    CGContextDrawImage(context, imageRect, image)
402
403    # Now the mask.
404    maskDataProvider = CGDataProviderCreateWithURL(theMaskingImageURL)
405    if maskDataProvider is None:
406        print >>sys.stderr, "Couldn't create Image Data provider!"
407        return
408
409    mask = CGImageMaskCreate(maskwidth, maskheight, bitsPerComponent,
410                            bitsPerComponent, maskwidth,
411                            maskDataProvider, None, shouldInterpolate)
412    del maskDataProvider
413    if mask is None:
414        print >>sys.stderr, "Couldn't create CGImageRef for mask data!"
415        return
416
417    # Draw the mask below the image. The current fill color (black)
418    # is painted through the mask.
419    maskRect = CGRectMake(0.0, 0.0, maskwidth, maskheight)
420    CGContextDrawImage(context, maskRect, mask)
421
422    # Create a new CGImage object, the image, masked with mask.
423    imageMaskedWithImage = CGImageCreateWithMask(image, mask)
424    # Once the new image is created, the code can release the image
425    # and the mask which make it up. Quartz retains what it needs
426    # for the new masked image 'imageMaskedWithImage'.
427    del image
428    del mask
429    if imageMaskedWithImage is None:
430        print >>sys.stderr, "Couldn't create image masked with mask!"
431        return
432
433    imageRect = CGRectMake(imagewidth + 10, imageheight/2, imagewidth, imageheight)
434    # Draw the masked image to the right of the image and its mask.
435    CGContextDrawImage(context, imageRect, imageMaskedWithImage)
436
437def doMaskImageWithGrayImageFromURL(context, imageURL, imagewidth, imageheight, bitsPerComponent,
438        theMaskingImageURL, maskwidth, maskheight):
439
440    imageBitsPerPixel = bitsPerComponent * 3
441    bytesPerRow = ( (imagewidth * imageBitsPerPixel) + 7)/8
442    shouldInterpolate = True
443
444    imageDataProvider = CGDataProviderCreateWithURL(imageURL)
445    if imageDataProvider is None:
446        print >>sys.stderr, "Couldn't create Image Data provider!"
447        return
448
449    colorspace = Utilities.getTheCalibratedRGBColorSpace()
450    image = CGImageCreate(imagewidth, imageheight, bitsPerComponent,
451                            imageBitsPerPixel, bytesPerRow, colorspace,
452                            kCGImageAlphaNone, imageDataProvider,
453                            None, shouldInterpolate,
454                            kCGRenderingIntentDefault)
455    del imageDataProvider
456    if image is None:
457        print >>sys.stderr, "Couldn't create CGImageRef for this data!"
458        return
459
460    imageRect = CGRectMake(0.,imageheight, imagewidth, imageheight)
461    # Draw the image.
462    CGContextDrawImage(context, imageRect, image)
463
464    # Now the mask.
465    maskDataProvider = CGDataProviderCreateWithURL(theMaskingImageURL)
466    if maskDataProvider is None:
467        print >>sys.stderr, "Couldn't create Image Data provider!"
468        return
469
470    # The color space for the image MUST be DeviceGray for it to
471    # be used as a masking image with CGImageCreateWithMask.
472    deviceGraySpace = CGColorSpaceCreateDeviceGray();
473    mask = CGImageCreate(maskwidth, maskheight, bitsPerComponent,
474                            bitsPerComponent, maskwidth,
475                            deviceGraySpace,
476                            kCGImageAlphaNone, maskDataProvider,
477                            None, shouldInterpolate,
478                            kCGRenderingIntentDefault)
479    # Release the color space since it is no longer needed.
480    del deviceGraySpace
481    del maskDataProvider
482
483    if mask is None:
484        print >>sys.stderr, "Couldn't create CGImageRef for gray image data!"
485        return
486
487    # Draw the mask below the image. The current fill color (black)
488    # is painted through the mask.
489    maskRect = CGRectMake(0., 0., maskwidth, maskheight)
490    CGContextDrawImage(context, maskRect, mask)
491
492    # Create a new CGImage object, the image, masked with mask.
493    imageMaskedWithImage = CGImageCreateWithMask(image, mask)
494
495    # Once the new image is created, the code can release the image
496    # and the mask which make it up. Quartz retains what it needs
497    # for the new masked image 'imageMaskedWithImage'.
498    del image
499    del mask
500
501    if imageMaskedWithImage is None:
502        print >>sys.stderr, "Couldn't create image masked with mask!"
503        return
504
505    imageRect = CGRectMake(imagewidth + 10, imageheight/2,
506                                                    imagewidth, imageheight)
507    # Draw the masked image to the right of the image and its mask.
508    CGContextDrawImage(context, imageRect, imageMaskedWithImage)
509    # Be sure and release the masked image.
510    del imageMaskedWithImage
511
512def doMaskImageWithColorFromURL(context, url,
513        width, height, isColor):
514
515    # This routine treats color images as RGB.
516    bitsPerComponent = 8
517    if isColor:
518        bitsPerPixel = bitsPerComponent * 3
519    else:
520        bitsPerPixel = bitsPerComponent
521
522    bytesPerRow = ( (width * bitsPerPixel) + 7)/8
523    shouldInterpolate = True
524
525    # This is a range of dark gray to black colors for an 8 bit per component
526    # image in a gray or RGB color space. The entries are image sample
527    # values of 0-0x1F for the first color component, 0-0x1F for the
528    # second color component, and so on. For image sample values where
529    # all components fall within the ranges in maskingColors, the sample
530    # value is masked and therefore unpainted.
531    maskingColors = (0x00, 0x1F, 0x00, 0x1F, 0x00, 0x1F)
532    backColor = (1., 0., 0., 1.) # Opaque red.
533
534    # Create a Quartz data provider from the supplied URL.
535    dataProvider = CGDataProviderCreateWithURL(url)
536    if dataProvider is None:
537        print >>sys.stderr, "Couldn't create Image data provider!"
538        return
539
540    # Create an image of the specified width, height and bits per pixel
541    # from the URL.
542    if isColor:
543        colorspace = Utilities.getTheCalibratedRGBColorSpace()
544    else:
545        colorspace = Utilities.getTheCalibratedGrayColorSpace()
546
547    image = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel,
548                                    bytesPerRow, colorspace, kCGImageAlphaNone,
549                                    dataProvider, None, shouldInterpolate,
550                                    kCGRenderingIntentDefault)
551    del dataProvider
552    if image is None:
553        print >>sys.stderr, "Couldn't create CGImageRef for this data!"
554        return
555
556    imageRect = CGRectMake(10., 10., width, height)
557    #CGContextScaleCTM(context, 0.33, 0.33)
558    # Set the color space and the color, then
559    # paint a red rectangle behind the image.
560    CGContextSetFillColorSpace(context, colorspace)
561    CGContextSetFillColor(context, backColor)
562    CGContextFillRect(context, imageRect)
563    # Draw the image into the rectangle.
564    CGContextDrawImage(context, imageRect, image)
565    # Create a new image from the original one, masking out a range
566    # of the blackest sample values.
567    imageMaskedWithColor = CGImageCreateWithMaskingColors(image, maskingColors)
568    # Release the original image; it is no longer needed.
569    del image
570    if imageMaskedWithColor is None:
571        print >>sys.stderr, "Couldn't create CGImageRef for masking color!"
572        return
573
574    # Paint the rectangle behind the next image with red.
575    imageRect = CGRectMake(30. + width, 10., width, height)
576    CGContextFillRect(context, imageRect)
577    # Draw the image. Image sample values in the range of
578    # the masking color are unpainted, allowing the background
579    # to show through.
580    CGContextDrawImage(context, imageRect, imageMaskedWithColor)
581
582
583if 1:	# Set to 1 for code in the book.
584
585    def drawWithClippingMask(context, theMaskingImageURL, imagewidth, imageheight):
586        # An array of CGColor objects.
587        colors = ( Utilities.getRGBOpaqueDarkGreenColor(), Utilities.getRGBOpaqueDarkBlueColor(),
588                Utilities.getRGBOpaqueBlueColor(), Utilities.getRGBOpaqueRedColor() )
589
590        imageBitsPerComponent = 8
591        bytesPerRow = imagewidth
592        shouldInterpolate = True
593        decode = (1, 0)
594
595        # Create the data.
596        dataProvider =  CGDataProviderCreateWithURL(theMaskingImageURL)
597        if dataProvider is None:
598            print >>sys.stderr, "Couldn't create Image data provider!"
599            return
600
601        cs = CGColorSpaceCreateDeviceGray()
602        image = CGImageCreate(imagewidth, imageheight,
603                        imageBitsPerComponent, imageBitsPerComponent,
604                        bytesPerRow, cs, kCGImageAlphaNone, dataProvider, decode,
605                        shouldInterpolate, kCGRenderingIntentDefault)
606        del cs
607        del dataProvider
608
609        if image is None:
610            print >>sys.stderr, "Couldn't create Image!"
611            return
612
613        imageRect = CGRectMake(0, 0, imagewidth*2/3, imageheight*2/3)
614
615        # Position for drawing the image at the left side of the figure.
616        CGContextTranslateCTM(context, 50, 50 )
617
618        # Draw the image.
619        CGContextDrawImage(context, imageRect, image)
620
621        # Position to the right of the image just painted.
622        CGContextTranslateCTM(context, CGRectGetWidth(imageRect) + 25,  0)
623
624        # Clip to the image.
625        CGContextClipToMask(context, imageRect, image)
626        # Release the image since this code no longer needs it.
627        del image
628
629        # Make a rect that has a width and height 1/3 that of the image.
630        rect = CGRectMake(0, 0, CGRectGetWidth(imageRect)/3, CGRectGetHeight(imageRect)/3)
631
632        CGContextTranslateCTM(context, 0, 2*CGRectGetHeight(rect))
633
634        # Draw a 3 x 3 grid of rectangles, setting the color for each rectangle
635        # by cycling through the array of CGColor objects in the 'colors' array.
636        for j in range(3):
637            CGContextSaveGState(context)
638            for i in range(3):
639                # Draw a row of rectangles.
640                # Set the fill color using one of the CGColor objects in the
641                # colors array.
642                CGContextSetFillColorWithColor(context, colors[(i+j) % 4])
643                CGContextFillRect(context, rect)
644                CGContextTranslateCTM(context, CGRectGetWidth(rect), 0)
645
646            CGContextRestoreGState(context)
647            # Position to draw the next row.
648            CGContextTranslateCTM(context, 0, -CGRectGetHeight(rect))
649
650else:
651    # This code works just fine to screen but when drawing to a PDF
652    # or printing context the masked drawing is completely masked out
653    # due to a bug in Quartz prior to Tiger 10.4.3.
654    def drawWithClippingMask(context, theMaskingImageURL, maskwidth, maskheight):
655        # An array of CGColor objects.
656        colors = (
657                Utilities.getRGBOpaqueDarkGreenColor(),
658                Utilities.getRGBOpaqueDarkBlueColor(),
659                Utilities.getRGBOpaqueBlueColor(),
660		Utilities.getRGBOpaqueRedColor())
661        maskBitsPerComponent = 8
662        bytesPerRow = ( (maskwidth * maskBitsPerComponent) + 7)/8
663        shouldInterpolate = True
664        maskDataProvider = CGDataProviderCreateWithURL(theMaskingImageURL)
665
666        if maskDataProvider is None:
667            print >>sys.stderr, "Couldn't create Image Mask provider!"
668	    return
669        mask = CGImageMaskCreate(maskwidth, maskheight, maskBitsPerComponent,
670                                        maskBitsPerComponent, maskwidth,
671                                        maskDataProvider, None, shouldInterpolate)
672        del maskDataProvider
673
674        if mask is None:
675            print >>sys.stderr, "Couldn't create Image Mask!"
676            return
677
678        maskRect = CGRectMake(0, 0, maskwidth/3, maskheight/3)
679
680        # Position for drawing the mask at the left side of the figure.
681        CGContextTranslateCTM(context, 50, 50 )
682        # Set the context fill color to a CGColor object that is black.
683        CGContextSetFillColorWithColor(context, getRGBOpaqueBlackColor())
684        # Draw the mask. It is painted with with the black fill color.
685        CGContextDrawImage(context, maskRect, mask)
686
687        # Position to the right of the mask just painted.
688        CGContextTranslateCTM(context, CGRectGetWidth(maskRect) + 25,  0)
689
690        # Clip to the mask.
691        CGContextClipToMask(context, maskRect, mask)
692        # Release the mask since this code no longer needs it.
693        del mask
694
695        # Make a rect that has a width and height 1/3 that of the image mask.
696        rect = CGRectMake(0, 0, CGRectGetWidth(maskRect)/3, CGRectGetHeight(maskRect)/3)
697
698        CGContextTranslateCTM(context, 0, 2*CGRectGetHeight(rect))
699
700        # Draw a 3 x 3 grid of rectangles, setting the color for each rectangle
701        # by cycling through the array of CGColor objects in the 'colors' array.
702        for j in range(3):
703            CGContextSaveGState(context)
704            for i in range(3):
705                # Draw a row of rectangles.
706                # Set the fill color using one of the CGColor objects in the
707                # colors array.
708                CGContextSetFillColorWithColor(context, colors[(i+j) % 4])
709                CGContextFillRect(context, rect)
710                CGContextTranslateCTM(context, CGRectGetWidth(rect), 0)
711            CGContextRestoreGState(context)
712            # Position to draw the next row.
713            CGContextTranslateCTM(context, 0, -CGRectGetHeight(rect))
714